package com.huangfu.learning.javabase.java.pattern.create.builder;

/**
 * Created with IntelliJ IDEA.
 * Author: huangfu.daohui
 * Date: 2018/8/7
 * Time: 18:14
 * Version: 1.0
 * Description: 建造者模式  使用多个简单的对象一步一步构建成一个复杂的对象。
 * https://www.cnblogs.com/liaoweipeng/p/5790603.html#commentform
 *http://www.runoob.com/design-pattern/builder-pattern.html
 * 应用实例： 1、去肯德基，汉堡、可乐、薯条、炸鸡翅等是不变的，而其组合是经常变化的，生成出所谓的"套餐"。 2、JAVA 中的 StringBuilder。
 * 优点： 1、建造者独立，易扩展。 2、便于控制细节风险。
 * 缺点： 1、产品必须有共同点，范围有限制。 2、如内部变化复杂，会有很多的建造类。
 * 使用场景： 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。
 * 注意事项：与工厂模式的区别是：建造者模式更加关注与零件装配的顺序。
 * 建造者模式的角色
 * ①建造者角色（Builder）
 * 对复杂对象的创建过程加以抽象，通过一个抽象接口来规范复杂对象的各个组成部分的构建；该接口规定了要实现复杂对象的各个部分的构建，不涉及具体对象的具体的构建。
 * ②具体创建者角色（ConcreteBuilder）
 * 1.实现Builder接口，针对不同的业务逻辑，具体化复杂对象的各个部分的创建；
 * 2.在建造过程完成后，提供产品的实例
 * ③指导者（Director）
 * 调用具体建造者来创建复杂对象的各个部分，在指导者中不涉及具体产品的信息，只负责保证对象各部分完整创建或者按某种顺序创建。
 * ④产品（Product）
 * 要创建的复杂的对象，一般来说包含多个部分或属性
 **/
public class BuilderPattern {

    // 测试
    public static void main(String[] args) {
        Director director = new Director();
        Product product = director.constructProduct( new ConcreteBuilder());
        System.out.println(product.getBasic());
        System.out.println(product.getWall());
        System.out.println(product.getRoofed());

    }
}

/**
 * 　* 具体的产品---房子
 **/
class Product {
    private String basic;//地基

    private String wall;//墙

    private String roofed;//楼顶

    public String getBasic() {
        return basic;
    }

    public void setBasic(String basic) {
        this.basic = basic;
    }

    public String getWall() {
        return wall;
    }

    public void setWall(String wall) {
        this.wall = wall;
    }

    public String getRoofed() {
        return roofed;
    }

    public void setRoofed(String roofed) {
        this.roofed = roofed;
    }

}

/**
 * 抽象建造
 */
interface Builder {

    /**
     * 打基础
     */
    void buildBasic();

    /**
     * 砌墙
     */
    void buildWalls();

    /**
     * 封顶
     */
    void roofed();

    /**
     * 造房子
     * 主要就是这个
     *
     * @return
     */
    Product buildProduct();
}

/**
 * 具体的建造
 */
class ConcreteBuilder implements Builder {

    private Product product;

    public ConcreteBuilder(){
        product = new Product();
    }
    @Override
    public void buildBasic() {
        product.setBasic("打好基础");
    }

    @Override
    public void buildWalls() {
        product.setWall("砌好墙");
    }

    @Override
    public void roofed() {
        product.setRoofed("封顶大吉");
    }

    @Override
    public Product buildProduct() {
        return product;
    }
}

/**
 * 建造者
 */
class Director {
    public Product constructProduct(Builder concreteBuilder) {
        concreteBuilder.buildBasic();
        concreteBuilder.buildWalls();
        concreteBuilder.roofed();
        return concreteBuilder.buildProduct();
    }
}